package ch.ti.bfh.app.loodel.internal.mail;

import ch.ti.bfh.app.loodel.domain.invitation.LearningEventInvitation;
import ch.ti.bfh.app.loodel.domain.learningEvent.LearningEvent;
import org.apache.commons.lang.StringUtils;
import org.apache.velocity.app.VelocityEngine;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.mail.javamail.MimeMessagePreparator;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.velocity.VelocityEngineUtils;

import javax.inject.Inject;
import javax.inject.Named;
import javax.mail.internet.MimeMessage;
import java.util.HashMap;
import java.util.Map;

@Service
@Transactional
public class DefaultLoodelMailService implements LoodelMailService {

    private final Logger logger = LoggerFactory.getLogger(DefaultLoodelMailService.class);

    private final JavaMailSender javaMailSender;

    private final VelocityEngine velocityEngine;

    @Value("${loodel.senderEMail}")
    private String senderMail;

    @Inject
    public DefaultLoodelMailService(JavaMailSender javaMailSender, @Named("velocityEngine") VelocityEngine velocityEngine) {
        this.javaMailSender = javaMailSender;
        this.velocityEngine = velocityEngine;
    }

    @Override
    public void sendLearningEventInvitationMail(final LearningEventInvitation learningEventInvitation, String customText) {
        final String mailsubject = "Loodel Learning Event Invitation";
        final String receiverMail = learningEventInvitation.getEMail();
        final String mailText = getLearningEventInvitationText(learningEventInvitation, customText);
        sendMail(mailsubject, receiverMail, mailText);
    }

    @Override
    public void sendLearningEventUpdateNofificationMail(LearningEvent learningEvent, String email) {
        String mailText = getLearningEventUpdateNotificationText(learningEvent, null);
        sendMail("Loodel Learning Event Update", email, mailText);
    }

    @Override
    public String getLearningEventUpdateNotificationText(LearningEvent learningEvent, String customText) {
        final Map<String, Object> velocityModelMap = new HashMap<String, Object>();
        velocityModelMap.put("learningEvent", learningEvent);
        velocityModelMap.put("sender", learningEvent.getOwner());
        return VelocityEngineUtils.mergeTemplateIntoString(velocityEngine, "/ch/ti/bfh/app/loodel/internal/learningEventNotification.vm", velocityModelMap);
    }

    @Override
    public String getLearningEventInvitationText(LearningEventInvitation learningEventInvitation, String customText) {
        final Map<String, Object> velocityModelMap = new HashMap<String, Object>();
        velocityModelMap.put("learningEvent", learningEventInvitation.getLearningEvent());
        velocityModelMap.put("userMail", learningEventInvitation.getEMail());
        velocityModelMap.put("sender", learningEventInvitation.getSender());
        if (StringUtils.isEmpty(customText)) {
            customText = null;
        }
        velocityModelMap.put("customText", customText);
        return VelocityEngineUtils.mergeTemplateIntoString(velocityEngine, "/ch/ti/bfh/app/loodel/internal/learningEventInvitation.vm", velocityModelMap);
    }

    private void sendMail(final String mailsubject, final String receiverMail, final String mailText) {
        MimeMessagePreparator preparator = new MimeMessagePreparator() {
            public void prepare(MimeMessage mimeMessage) throws Exception {
                MimeMessageHelper message = new MimeMessageHelper(mimeMessage, true, "UTF-8");
                message.setTo(receiverMail);
                message.setFrom(senderMail);
                message.setText(mailText, true);
                message.setSubject(mailsubject);
                logger.debug("Send Mail From: '{}' To: '{}' Subject: '{}'", new Object[]{senderMail, receiverMail, mailsubject});
            }
        };
        this.javaMailSender.send(preparator);
    }

}
